package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"trade_mq/chain"
	"trade_mq/database"
	"trade_mq/global"
	"trade_mq/rabbitmq"
	"trade_mq/util/register/consul"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
)

func main() {

	// mode 开发模式,local, dev,test,prod
	mode := os.Getenv("BUILD_ENV")

	if mode == "" {
		mode = "local"
	}
	quit := make(chan os.Signal, 1)
	defer func() {
		if err := recover(); err != nil {
			zap.L().Error("运行时错误", zap.Any("err", err))
			quit <- syscall.SIGQUIT
		}
	}()

	// 获取是否是debug模式
	isDebug := mode == "dev"

	// 初始化logger
	global.InitLogger(!isDebug)

	// 初始化配置
	global.InitConfig(mode)

	// 初始化数据库
	database.InitDatabase(!isDebug)

	// 初始化 rabbitmq
	rabbitmq.InitRabbitMQ(!isDebug)

	// 初始化 cli
	chain.InitTradeManager(mode)

	port := global.ServiceConfig.Port

	// 健康检查
	eg := gin.Default()
	eg.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"code":    http.StatusOK,
			"message": "success",
		})
	})
	srv := &http.Server{
		Addr:    fmt.Sprintf(":%d", port),
		Handler: eg.Handler(),
	}

	go func() {
		// 服务连接
		if err := srv.ListenAndServe(); err != nil {
			zap.L().Error("close server", zap.Error(err))
		}
	}()

	// 注册服务
	registry := consul.NewRegistry(global.ServiceConfig.Consul.Host, global.ServiceConfig.Consul.Port)
	serviceId := uuid.Must(uuid.NewUUID()).String()
	err := registry.Register(global.ServiceConfig.Host, port, global.ServiceConfig.Name, global.ServiceConfig.Tags, serviceId)
	if err != nil {
		zap.L().Panic("register failed", zap.Error(err))
		return
	}

	// 优雅退出
	// kill -9 是捕捉不到的
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	// 注销服务
	err = registry.DeRegister(serviceId)
	if err != nil {
		zap.L().Error("注销consul失败", zap.Error(err))
	}

	err = srv.Shutdown(context.Background())
	if err != nil {
		zap.L().Error("shutdown server 失败", zap.Error(err))
	}

	// 同步log信息
	zap.S().Sync()

	// close rabbitmq
	global.Manager.Close()

}
